home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / asm / gassrc.zip / emx / gnu / gas-1.38 / as.c < prev    next >
C/C++ Source or Header  |  1993-11-06  |  9KB  |  321 lines

  1. /* as.c -- changed for emx by Eberhard Mattes -- Aug 1992 */
  2.  
  3. /* as.c - GAS main program.
  4.    Copyright (C) 1987 Free Software Foundation, Inc.
  5.  
  6. This file is part of GAS, the GNU Assembler.
  7.  
  8. GAS is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 1, or (at your option)
  11. any later version.
  12.  
  13. GAS is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with GAS; see the file COPYING.  If not, write to
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22. /*
  23.  * Main program for AS; a 32-bit assembler of GNU.
  24.  * Understands command arguments.
  25.  * Has a few routines that don't fit in other modules because they
  26.  * are shared.
  27.  *
  28.  *
  29.  *            bugs
  30.  *
  31.  * : initialisers
  32.  *    Since no-one else says they will support them in future: I
  33.  * don't support them now.
  34.  *
  35.  */
  36.  
  37. #ifdef _POSIX_SOURCE
  38. #include <sys/types.h>    /* For pid_t in signal.h */
  39. #endif
  40. #include <signal.h>
  41.  
  42. #define COMMON
  43. #include "as.h"
  44. #include "struc-symbol.h"
  45. #include "write.h"
  46.         /* Warning!  This may have some slightly strange side effects
  47.            if you try to compile two or more assemblers in the same
  48.            directory!
  49.          */
  50.  
  51. #ifndef SIGTY
  52. #define SIGTY int
  53. #endif
  54.  
  55. SIGTY got_sig();
  56.  
  57. #ifdef DONTDEF
  58. static char * gdb_symbol_file_name;
  59. long int gdb_begin();
  60. #endif
  61.  
  62. char *myname;        /* argv[0] */
  63. extern char version_string[];
  64.  
  65. main(argc,argv)
  66. int    argc;
  67. char    **argv;
  68. {
  69.     int    work_argc;    /* variable copy of argc */
  70.     char    **work_argv;    /* variable copy of argv */
  71.     char    *arg;        /* an arg to program */
  72.     char    a;        /* an arg flag (after -) */
  73.     static const int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
  74.  
  75.     extern int bad_error;    /* Did we hit a bad error ? */
  76.  
  77.     char    *stralloc();    /* Make a (safe) copy of a string. */
  78.     void    symbol_begin();
  79.     void    read_begin();
  80.     void    write_object_file();
  81.  
  82.     for(a=0;sig[a]!=0;a++)
  83.         if(signal(sig[a], SIG_IGN) != SIG_IGN)
  84.             signal(sig[a], got_sig);
  85.  
  86.     myname=argv[0];
  87.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  88.     out_file_name    = "a.out";    /* default .o file */
  89.     symbol_begin();        /* symbols.c */
  90.     subsegs_begin();        /* subsegs.c */
  91.     read_begin();            /* read.c */
  92.     md_begin();            /* MACHINE.c */
  93.     input_scrub_begin();        /* input_scrub.c */
  94. #ifdef DONTDEF
  95.     gdb_symbol_file_name = 0;
  96. #endif
  97.  
  98. #ifdef __EMX__
  99.   _emxload_env ("GCCLOAD");
  100. #endif
  101.  
  102.     /*
  103.      * Parse arguments, but we are only interested in flags.
  104.      * When we find a flag, we process it then make it's argv[] NULL.
  105.      * This helps any future argv[] scanners avoid what we processed.
  106.      * Since it is easy to do here we interpret the special arg "-"
  107.      * to mean "use stdin" and we set that argv[] pointing to "".
  108.      * After we have munged argv[], the only things left are source file
  109.      * name(s) and ""(s) denoting stdin. These file names are used
  110.      * (perhaps more than once) later.
  111.      */
  112.     work_argc = argc-1;        /* don't count argv[0] */
  113.     work_argv = argv+1;        /* skip argv[0] */
  114.     for (;work_argc--;work_argv++) {
  115.         arg = * work_argv;    /* work_argv points to this argument */
  116.  
  117.         if (*arg!='-')        /* Filename. We need it later. */
  118.             continue;    /* Keep scanning args looking for flags. */
  119.         if (arg[1] == '-' && arg[2] == 0) {
  120.             /* "--" as an argument means read STDIN */
  121.             /* on this scan, we don't want to think about filenames */
  122.             * work_argv = "";    /* Code that means 'use stdin'. */
  123.             continue;
  124.         }
  125.                 /* This better be a switch. */
  126.         arg ++;        /* -> letter. */
  127.  
  128.         while (a = * arg)  {/* scan all the 1-char flags */
  129.             arg ++;    /* arg -> after letter. */
  130.             a &= 0x7F;    /* ascii only please */
  131.             if (flagseen[a])
  132.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  133.             flagseen[a] = TRUE;
  134.             switch (a) {
  135.             case 'f':
  136.                 break;    /* -f means fast - no need for "app" preprocessor. */
  137.  
  138.             case 'D':
  139.                 /* DEBUG is implemented: it debugs different */
  140.                 /* things to other people's assemblers. */
  141.                 break;
  142.  
  143. #ifdef DONTDEF
  144.             case 'G':    /* GNU AS switch: include gdbsyms. */
  145.                 if (*arg)    /* Rest of argument is file-name. */
  146.                     gdb_symbol_file_name = stralloc (arg);
  147.                 else if (work_argc) {    /* Next argument is file-name. */
  148.                     work_argc --;
  149.                     * work_argv = NULL; /* Not a source file-name. */
  150.                     gdb_symbol_file_name = * ++ work_argv;
  151.                 } else
  152.                     as_warn( "%s: I expected a filename after -G",myname);
  153.                 arg = "";    /* Finished with this arg. */
  154.                 break;
  155. #endif
  156.  
  157. #ifndef WORKING_DOT_WORD
  158.             case 'k':
  159.                 break;
  160. #endif
  161.  
  162.             case 'L': /* -L means keep L* symbols */
  163.                 break;
  164.  
  165.             case 'o':
  166.                 if (*arg)    /* Rest of argument is object file-name. */
  167.                     out_file_name = stralloc (arg);
  168.                 else if (work_argc) {    /* Want next arg for a file-name. */
  169.                     * work_argv = NULL; /* This is not a file-name. */
  170.                     work_argc--;
  171.                     out_file_name = * ++ work_argv;
  172.                 } else
  173.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  174.                 arg = "";    /* Finished with this arg. */
  175.                 break;
  176.  
  177.             case 'R':
  178.                 /* -R means put data into text segment */
  179.                 break;
  180.  
  181.             case 'v':
  182. #ifdef    VMS
  183.                 {
  184.                 extern char *compiler_version_string;
  185.                 compiler_version_string = arg;
  186.                 }
  187. #else /* not VMS */
  188.                 fprintf(stderr,version_string);
  189.                 if(*arg && strcmp(arg,"ersion"))
  190.                     as_warn("Unknown -v option ignored");
  191. #endif
  192.                 while(*arg) arg++;    /* Skip the rest */
  193.                 break;
  194.  
  195. #if defined (__EMX__)
  196.             case 'w':
  197.                 /* -w means insert wait instruction */
  198.                 break;
  199. #endif
  200.             case 'W':
  201.                 /* -W means don't warn about things */
  202.                 break;
  203.  
  204.             default:
  205.                 --arg;
  206.                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  207.                     as_warn("%s: I don't understand '%c' flag!",myname,a);
  208.                 if(arg && *arg)
  209.                     arg++;
  210.                 break;
  211.             }
  212.         }
  213.         /*
  214.          * We have just processed a "-..." arg, which was not a
  215.          * file-name. Smash it so the
  216.          * things that look for filenames won't ever see it.
  217.          *
  218.          * Whatever work_argv points to, it has already been used
  219.          * as part of a flag, so DON'T re-use it as a filename.
  220.          */
  221.         *work_argv = NULL; /* NULL means 'not a file-name' */
  222.     }
  223. #ifdef DONTDEF
  224.     if (gdb_begin(gdb_symbol_file_name) == 0)
  225.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  226. #endif
  227.     /* Here with flags set up in flagseen[]. */
  228.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  229.     if (seen_at_least_1_file() && !bad_error)
  230.         write_object_file();/* relax() addresses then emit object file */
  231.     input_scrub_end();
  232.     md_end();            /* MACHINE.c */
  233. #ifndef    VMS
  234.     exit(bad_error);            /* WIN */
  235. #else    /* VMS */
  236.     exit(!bad_error);            /* WIN */
  237. #endif    /* VMS */
  238. }
  239.  
  240.  
  241. /*            perform_an_assembly_pass()
  242.  *
  243.  * Here to attempt 1 pass over each input file.
  244.  * We scan argv[*] looking for filenames or exactly "" which is
  245.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  246.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  247.  * expressions of the form (unknown value)+-(unknown value).
  248.  *
  249.  * Note the un*x semantics: there is only 1 logical input file, but it
  250.  * may be a catenation of many 'physical' input files.
  251.  */
  252. perform_an_assembly_pass (argc, argv)
  253. int    argc;
  254. char **    argv;
  255. {
  256.     char *    buffer;        /* Where each bufferful of lines will start. */
  257.     void    read_a_source_file();
  258.     int saw_a_file = 0;
  259.  
  260.     text_fix_root        = NULL;
  261.     data_fix_root        = NULL;
  262.     need_pass_2        = FALSE;
  263.  
  264.     argv++;            /* skip argv[0] */
  265.     argc--;            /* skip argv[0] */
  266.     while (argc--) {
  267.         if (*argv) {        /* Is it a file-name argument? */
  268.             /* argv -> "" if stdin desired, else -> filename */
  269.             if (buffer = input_scrub_new_file (*argv) ) {
  270.                 saw_a_file++;
  271.                 read_a_source_file(buffer);
  272.             }
  273.         }
  274.         argv++;            /* completed that argv */
  275.     }
  276.     if(!saw_a_file)
  277.         if(buffer = input_scrub_new_file("") )
  278.             read_a_source_file(buffer);
  279. }
  280.  
  281. /*
  282.  *            stralloc()
  283.  *
  284.  * Allocate memory for a new copy of a string. Copy the string.
  285.  * Return the address of the new string. Die if there is any error.
  286.  */
  287.  
  288. char *
  289. stralloc (str)
  290. char *    str;
  291. {
  292.     register char *    retval;
  293.     register long int    len;
  294.  
  295.     len = strlen (str) + 1;
  296.     retval = xmalloc (len);
  297.     (void)strcpy (retval, str);
  298.     return (retval);
  299. }
  300.  
  301. lose()
  302. {
  303.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  304. }
  305.  
  306. SIGTY
  307. got_sig(sig)
  308. int sig;
  309. {
  310.     static here_before = 0;
  311.  
  312.     as_bad("Interrupted by signal %d",sig);
  313.     if(here_before++)
  314.         exit(1);
  315. #if defined (__EMX__)
  316.     signal (sig, SIG_DFL);
  317. #endif
  318. }
  319.  
  320. /* end: as.c */
  321.